#ifndef	__BFX_XMLCHARTYPE_H__
#define	__BFX_XMLCHARTYPE_H__

namespace BFX
{

// class is used for quick character type recognition which is optimized for the first 127 ascii characters.
class XMLCharType
{
private:
	XMLCharType();

public:
	static bool IsWhiteSpace(UCHAR ch)
	{
		return (s_pCharProperties[ch] & Whitespace) != 0;
	}
	static bool IsLetter(UCHAR ch)
	{
		return (s_pCharProperties[ch] & Letter) != 0;
	}
	static bool IsNCNameChar(UCHAR ch)
	{
		return (s_pCharProperties[ch] & NCName) != 0;
	}
	static bool IsStartNCNameChar(UCHAR ch)
	{
		return (s_pCharProperties[ch] & NCStartName) != 0;
	}
	static bool IsCharData(UCHAR ch)
	{
		return (s_pCharProperties[ch] & CharData) != 0;
	}
	// #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] Section 2.3 of spec
	static bool IsPubidChar(UCHAR ch)
	{
		return (s_pCharProperties[ch] & PublicId) != 0;
	}
	// CharData - { 0xA, 0xD, '<', '&', ']' }
	static bool IsTextChar(UCHAR ch)
	{
		return (s_pCharProperties[ch] & Text ) != 0;
	}
	// CharData - { 0xA, 0xD, 0x9, '<', '>', '&', '\'', '"' }
	static bool IsAttributeValueChar(UCHAR ch)
	{
		return (s_pCharProperties[ch] & AttrValue) != 0;
	}
	static bool IsNameChar(UCHAR ch)
	{
		return IsNCNameChar(ch) || ch == ':';
	}
	static bool IsStartNameChar(UCHAR ch)
	{
		return IsStartNCNameChar(ch) || ch == ':';
	}
	static bool IsDigit(UCHAR ch)
	{
		return (ch >= 0x30 && ch <= 0x39);
	}
	bool IsHexDigit(UCHAR ch)
	{
		return (ch >= 0x30 && ch <= 0x39) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
	}

private:
	static const int Whitespace    = 1;
	static const int Letter        = 2;
    static const int NCStartName   = 4;
    static const int NCName        = 8;
    static const int CharData      = 16;
    static const int PublicId      = 32;
    static const int Text          = 64;
    static const int AttrValue     = 128;

	static BYTE	s_pCharProperties[];
};

}	//	namespace BFX

#endif	//	__BFX_XMLCHARTYPE_H__
